﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

namespace JinYuan.MES
{
    public static class MESApiHelper
    {
        private static readonly HttpClient _httpClient;
        private static string _appId;
        private static string _appKey;
        private static string _token;
        private static DateTime _tokenExpireTime;

        private const string TOKEN_URL = "https://example.com/api/oauth/token"; // Token 获取地址

        static MESApiHelper()
        {
            _httpClient = new HttpClient();
            _httpClient.Timeout = TimeSpan.FromSeconds(10); // 设置默认超时
        }

        /// <summary>
        /// 初始化 AppId 和 AppKey
        /// </summary>
        /// <param name="appId"></param>
        /// <param name="appKey"></param>
        public static void Initialize(string appId, string appKey)
        {
            _appId = appId;
            _appKey = appKey;
        }

        /// <summary>
        /// 确保 Token 有效
        /// </summary>
        private static async Task EnsureTokenValidAsync()
        {
            if (string.IsNullOrEmpty(_token) || DateTime.Now >= _tokenExpireTime)
            {
                await RefreshTokenAsync();
            }
        }

        /// <summary>
        /// 刷新 Token
        /// </summary>
        private static async Task RefreshTokenAsync()
        {
            var tokenRequest = new
            {
                appId = _appId,
                appKey = _appKey
            };

            var response = await SendRequestAsync<TokenResponse>(TOKEN_URL, HttpMethod.Post, tokenRequest, false);

            if (response != null && response.Success)
            {
                _token = response.Token;
                _tokenExpireTime = DateTime.Now.AddSeconds(response.Expire);
            }
            else
            {
                throw new Exception("获取 Token 失败");
            }
        }

        /// <summary>
        /// 发送 HTTP 请求
        /// </summary>
        /// <typeparam name="T">返回类型</typeparam>
        /// <param name="url">请求地址</param>
        /// <param name="method">HTTP 方法</param>
        /// <param name="data">请求数据</param>
        /// <param name="requiresAuth">是否需要认证</param>
        /// <returns></returns>
        public static async Task<T> SendRequestAsync<T>(string url, HttpMethod method, object data = null, bool requiresAuth = true)
        {
            if (requiresAuth)
            {
                await EnsureTokenValidAsync();
            }

            using (var request = new HttpRequestMessage(method, url))
            {
                if (requiresAuth)
                {
                    request.Headers.Add("Authorization", $"Bearer {_token}");
                }

                if (data != null)
                {
                    var json = JsonConvert.SerializeObject(data);
                    request.Content = new StringContent(json, Encoding.UTF8, "application/json");
                }

                var response = await _httpClient.SendAsync(request);
                var content = await response.Content.ReadAsStringAsync();

                if (!response.IsSuccessStatusCode)
                {
                    throw new HttpRequestException($"请求失败: {response.StatusCode}, {content}");
                }

                return JsonConvert.DeserializeObject<T>(content);
            }
        }

        /// <summary>
        /// 发送 HTTP 请求并返回字符串
        /// </summary>
        /// <param name="url">请求地址</param>
        /// <param name="method">HTTP 方法</param>
        /// <param name="data">请求数据</param>
        /// <param name="requiresAuth">是否需要认证</param>
        /// <returns></returns>
        public static async Task<string> SendRequestStringAsync(string url, HttpMethod method, object data = null, bool requiresAuth = true)
        {
            if (requiresAuth)
            {
                await EnsureTokenValidAsync();
            }

            using (var request = new HttpRequestMessage(method, url))
            {
                if (requiresAuth)
                {
                    request.Headers.Add("Authorization", $"Bearer {_token}");
                }

                if (data != null)
                {
                    //var json = JsonConvert.SerializeObject(data);
                    request.Content = new StringContent(data.ToString(), Encoding.UTF8, "application/json");
                }

                var response = await _httpClient.SendAsync(request);
                var content = await response.Content.ReadAsStringAsync();

                if (!response.IsSuccessStatusCode)
                {
                    throw new HttpRequestException($"请求失败: {response.StatusCode}, {content}");
                }

                return content;
            }
        }

        /// <summary>
        /// 获取 OCV 数据
        /// </summary>
        /// <param name="url">请求地址</param>
        /// <param name="warehouseCode">仓库代码</param>
        /// <param name="customerCode">客户代码</param>
        /// <param name="stdSnList">序列号列表</param>
        /// <returns></returns>
        public static async Task<string> GetOcvListAsync(string url, string warehouseCode, string customerCode, List<string> stdSnList)
        {
            var request = new
            {
                warehouseCode = warehouseCode,
                customerCode = customerCode,
                stdSnList = stdSnList
            };

            return await SendRequestStringAsync(url, HttpMethod.Post, request, true);
        }

        /// <summary>
        /// 上传检测结果
        /// </summary>
        /// <param name="url">请求地址</param>
        /// <param name="request">检测请求数据</param>
        /// <returns></returns>
        public static async Task<InspectionResponse> UploadInspectionResultAsync(string url, InspectionRequest request)
        {
            return await SendRequestAsync<InspectionResponse>(url, HttpMethod.Post, request, true);
        }
    }

    /// <summary>
    /// Token 响应模型
    /// </summary>
    public class TokenResponse
    {
        public bool Success { get; set; }
        public string Token { get; set; }
        public int Expire { get; set; }
    }

    /// <summary>
    /// 检测请求模型
    /// </summary>
    public class InspectionRequest
    {
        public string WarehouseCode { get; set; }
        public string CustomerCode { get; set; }
        public List<string> SnList { get; set; }
    }

    /// <summary>
    /// 检测响应模型
    /// </summary>
    public class InspectionResponse
    {
        public bool Success { get; set; }
        public string Message { get; set; }
    }
}
